home *** CD-ROM | disk | FTP | other *** search
- Date: Fri, 22 Jul 1994 17:24:38 -0400
- From: "Nicholas S Castellano" <entropy@terminator.rs.itd.umich.edu>
- To: mint@terminator.rs.itd.umich.edu
- Subject: Tsetitimer()
-
-
- Here's an implementation of Tsetitimer(), providing interval timers
- like the BSD setitimer()/getitimer() system calls.
-
-
- diff -u ../old/dos.c ./dos.c
- --- ../old/dos.c Fri Jul 22 03:48:08 1994
- +++ ./dos.c Fri Jul 22 05:53:48 1994
- @@ -478,6 +478,211 @@
- return oldalarm;
- }
-
- +#define ITIMER_REAL 0
- +#define ITIMER_VIRTUAL 1
- +#define ITIMER_PROF 2
- +
- +/*
- + * helper function for t_setitimer: this will be called when the ITIMER_REAL
- + * timer goes off
- + */
- +
- +static void
- +itimer_real_me(p)
- + PROC *p;
- +{
- + PROC *real_curproc;
- +
- + real_curproc = curproc;
- + curproc = p;
- + if (p->itimer[ITIMER_REAL].interval)
- + p->itimer[ITIMER_REAL].timeout =
- + addtimeout(p->itimer[ITIMER_REAL].interval, itimer_real_me);
- + else
- + p->itimer[ITIMER_REAL].timeout = 0;
- +
- + curproc = real_curproc;
- + post_sig(p, SIGALRM);
- +}
- +
- +/*
- + * helper function for t_setitimer: this will be called when the ITIMER_VIRTUAL
- + * timer goes off
- + */
- +
- +static void
- +itimer_virtual_me(p)
- + PROC *p;
- +{
- + PROC *real_curproc;
- + long timeleft;
- +
- + real_curproc = curproc;
- + curproc = p;
- + timeleft = p->itimer[ITIMER_VIRTUAL].reqtime
- + - (p->systime - p->itimer[ITIMER_VIRTUAL].startsystime);
- + if (timeleft > 0) {
- + p->itimer[ITIMER_VIRTUAL].timeout =
- + addtimeout(timeleft, itimer_virtual_me);
- + } else {
- + timeleft = p->itimer[ITIMER_VIRTUAL].interval;
- + if (timeleft == 0) {
- + p->itimer[ITIMER_VIRTUAL].timeout = 0;
- + } else {
- + p->itimer[ITIMER_VIRTUAL].reqtime = timeleft;
- + p->itimer[ITIMER_VIRTUAL].startsystime = p->systime;
- + p->itimer[ITIMER_VIRTUAL].startusrtime = p->usrtime;
- + p->itimer[ITIMER_VIRTUAL].timeout =
- + addtimeout(timeleft, itimer_virtual_me);
- + }
- + post_sig(p, SIGVTALRM);
- + }
- + curproc = real_curproc;
- +}
- +
- +/*
- + * helper function for t_setitimer: this will be called when the ITIMER_PROF
- + * timer goes off
- + */
- +
- +static void
- +itimer_prof_me(p)
- + PROC *p;
- +{
- + PROC *real_curproc;
- + long timeleft;
- +
- + real_curproc = curproc;
- + curproc = p;
- + timeleft = p->itimer[ITIMER_PROF].reqtime
- + - (p->systime - p->itimer[ITIMER_PROF].startsystime)
- + - (p->usrtime - p->itimer[ITIMER_PROF].startusrtime);
- + if (timeleft > 0) {
- + p->itimer[ITIMER_PROF].timeout =
- + addtimeout(timeleft, itimer_prof_me);
- + } else {
- + timeleft = p->itimer[ITIMER_PROF].interval;
- + if (timeleft == 0) {
- + p->itimer[ITIMER_PROF].timeout = 0;
- + } else {
- + p->itimer[ITIMER_PROF].reqtime = timeleft;
- + p->itimer[ITIMER_PROF].startsystime = p->systime;
- + p->itimer[ITIMER_PROF].startusrtime = p->usrtime;
- + p->itimer[ITIMER_PROF].timeout =
- + addtimeout(timeleft, itimer_prof_me);
- + }
- + post_sig(p, SIGPROF);
- + }
- + curproc = real_curproc;
- +}
- +
- +/*
- + * t_setitimer(which, interval, value, ointerval, ovalue):
- + * schedule an interval timer
- + * which is ITIMER_REAL (0) for SIGALRM, ITIMER_VIRTUAL (1) for SIGVTALRM,
- + * or ITIMER_PROF (2) for SIGPROF.
- + * the rest of the parameters are pointers to millisecond values.
- + * interval is the value to which the timer will be reset
- + * value is the current timer value
- + * ointerval and ovalue are the previous values
- + */
- +
- +long ARGS_ON_STACK
- +t_setitimer(which, interval, value, ointerval, ovalue)
- + short which;
- + long *interval;
- + long *value;
- + long *ointerval;
- + long *ovalue;
- +{
- + long oldtimer;
- + TIMEOUT *t;
- + void (*handler)() = 0;
- + long tmpold;
- +
- + if ((which != ITIMER_REAL) && (which != ITIMER_VIRTUAL)
- + && (which != ITIMER_PROF)) {
- + return EINVFN;
- + }
- +
- +/* ensure that any addresses specified by the calling process are in that
- + process's address space
- +*/
- + if ((interval && (!(valid_address((long) interval))))
- + || (value && (!(valid_address((long) value))))
- + || (ointerval && (!(valid_address((long) ointerval))))
- + || (ovalue && (!(valid_address((long) ovalue))))) {
- + return EIMBA;
- + }
- +
- +/* see how many milliseconds there were to the timeout */
- + oldtimer = 0;
- +
- + if (curproc->itimer[which].timeout) {
- + for (t = tlist; t; t = t->next) {
- + oldtimer += t->when;
- + if (t == curproc->itimer[which].timeout)
- + goto foundtimer;
- + }
- + DEBUG(("Tsetitimer: old timer not found!"));
- + oldtimer = 0;
- +foundtimer:
- + ;
- + }
- +
- + if (ointerval)
- + *ointerval = curproc->itimer[which].interval;
- + if (ovalue) {
- + if (which == ITIMER_REAL) {
- + *ovalue = oldtimer;
- + } else {
- + tmpold = curproc->itimer[which].reqtime
- + - (curproc->systime - curproc->itimer[which].startsystime);
- + if (which == ITIMER_PROF)
- + tmpold -=
- + (curproc->usrtime - curproc->itimer[which].startusrtime);
- + if (tmpold <= 0)
- + tmpold = 0;
- + *ovalue = tmpold;
- + }
- + }
- + if (interval)
- + curproc->itimer[which].interval = *interval;
- + if (value) {
- +/* cancel old timer */
- + if (curproc->itimer[which].timeout)
- + canceltimeout(curproc->itimer[which].timeout);
- + curproc->itimer[which].timeout = 0;
- +
- +/* add a new timer, to occur in x milliseconds */
- + if (*value) {
- + curproc->itimer[which].reqtime = *value;
- + curproc->itimer[which].startsystime =
- + curproc->systime;
- + curproc->itimer[which].startusrtime =
- + curproc->usrtime;
- + switch (which) {
- + case ITIMER_REAL:
- + handler = itimer_real_me;
- + break;
- + case ITIMER_VIRTUAL:
- + handler = itimer_virtual_me;
- + break;
- + case ITIMER_PROF:
- + handler = itimer_prof_me;
- + break;
- + default:
- + break;
- + }
- + curproc->itimer[which].timeout =
- + addtimeout(*value, handler);
- + }
- + else
- + curproc->itimer[which].timeout = 0;
- + }
- + return 0;
- +}
- +
- /*
- * sysconf(which): returns information about system configuration.
- * "which" specifies which aspect of the system configuration is to
- @@ -697,4 +902,5 @@
- dos_tab[0x146] = p_setauid;
- dos_tab[0x147] = p_getgroups;
- dos_tab[0x148] = p_setgroups;
- + dos_tab[0x149] = t_setitimer;
- }
- diff -u ../old/proc.c ./proc.c
- --- ../old/proc.c Fri Jul 22 03:48:56 1994
- +++ ./proc.c Fri Jul 22 03:15:54 1994
- @@ -116,6 +116,15 @@
- p->slices = SLICES(p->pri);
- p->starttime = timestamp;
- p->startdate = datestamp;
- + p->itimer[0].interval = 0;
- + p->itimer[0].reqtime = 0;
- + p->itimer[0].timeout = 0;
- + p->itimer[1].interval = 0;
- + p->itimer[1].reqtime = 0;
- + p->itimer[1].timeout = 0;
- + p->itimer[2].interval = 0;
- + p->itimer[2].reqtime = 0;
- + p->itimer[2].timeout = 0;
-
- ((long *)p->sysstack)[1] = FRAME_MAGIC;
- ((long *)p->sysstack)[2] = 0;
- diff -u ../old/proc.h ./proc.h
- --- ../old/proc.h Fri Jul 22 03:48:58 1994
- +++ ./proc.h Wed Jul 20 13:16:44 1994
- @@ -69,6 +69,14 @@
- void (*func) P_((struct proc *)); /* function to call at timeout */
- short flags;
- } TIMEOUT;
- +
- +struct itimervalue {
- + TIMEOUT *timeout;
- + long interval;
- + long reqtime;
- + long startsystime;
- + long startusrtime;
- +};
-
- #ifndef GENMAGIC
- extern TIMEOUT *tlist;
- @@ -224,6 +232,7 @@
- #define NGROUPMAX 8
- short ngroups; /* ts: number of supplementary groups */
- short ngroup[NGROUPMAX]; /* ts: supplementary groups */
- + struct itimervalue itimer[3]; /* interval timers */
- } PROC;
-
-
- diff -u ../old/proto.h ./proto.h
- --- ../old/proto.h Fri Jul 22 03:50:08 1994
- +++ ./proto.h Fri Jul 22 04:15:26 1994
- @@ -93,6 +93,7 @@
- long ARGS_ON_STACK p_pause P_((void));
- long ARGS_ON_STACK t_alarm P_((long x));
- long ARGS_ON_STACK t_malarm P_((long x));
- +long ARGS_ON_STACK t_setitimer P_((short which, long *interval, long *value, long *ointerval, long *ovalue));
- long ARGS_ON_STACK s_ysconf P_((int which));
- long ARGS_ON_STACK s_alert P_((char *msg));
- void init_dos P_((void));
-
- --
- entropy -- it's not just a good idea, it's the second law.
- Personal mail: entropy@gnu.ai.mit.edu
- MiNT library mail: entropy@terminator.rs.itd.umich.edu
- "what do you have against octal?" -jrb
-
-